package com.jrx.anytxn.customer.service.impl;

import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.customer.constant.CustomerConstant;
import com.jrx.anytxn.customer.constant.ErrorMsgConstant;
import com.jrx.anytxn.customer.dto.customer.CustomerLabelReq;
import com.jrx.anytxn.customer.dto.customer.CustomerLabelRes;
import com.jrx.anytxn.customer.entity.CmCustomerLabel;
import com.jrx.anytxn.customer.entity.CmCustomerSecondLevel;
import com.jrx.anytxn.customer.mapper.base.CmCustomerLabelMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerLabelMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerSecondLevelMapper;
import com.jrx.anytxn.customer.service.ICustomerLabelService;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.entity.PrPriceLabel;
import com.jrx.anytxn.param.entity.TlCustomerLabelLog;
import com.jrx.anytxn.param.service.rights.IPrPriceLabelService;
import com.jrx.anytxn.param.service.rights.ITlCustomerLabelLogService;
import com.jrx.anytxn.sharding.pojo.entity.CacheMapping;
import com.jrx.anytxn.sharding.service.ICacheMappingService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CustomerLabelServiceImpl implements ICustomerLabelService {

    private static Logger logger = LoggerFactory.getLogger(CustomerLabelServiceImpl.class);

    @Resource
    private ExtCmCustomerSecondLevelMapper extCmCustomerSecondLevelMapper;
    @Autowired
    private ISegmentService segmentService;
    @Resource
    private CmCustomerLabelMapper cmCustomerLabelMapper;
    @Resource
    private ExtCmCustomerLabelMapper extCmCustomerLabelMapper;
    @Autowired
    private IPrPriceLabelService prPriceLabelService;
    @Autowired(required = false)
    private ICacheMappingService cacheMappingService;
    @Autowired
    ITlCustomerLabelLogService tlCustomerLabelLogService;

    @Override
    public CustomerLabelRes addCustomerLabel(CustomerLabelReq req) throws TxnBizException {
        if(StringUtils.isBlank(req.getIdNumber()) && StringUtils.isBlank(req.getMobile())){
            logger.error("证件号，手机号不能同时为空");
            throw new TxnBizException(TxnRespCode.NOT_EMPTY.getCode(), TxnRespCode.NOT_EMPTY.getUserTips());
        }

        PrPriceLabel prPriceLabel = prPriceLabelService.findByLabelCodeAndTenId(req.getLabelCode(),req.getTenantId());

        if(null == prPriceLabel){
            logger.error("未匹配到定价标签，标签编号：{}",req.getLabelCode());
            throw new TxnBizException(TxnRespCode.PARAM_ERROR.getCode(), TxnRespCode.PARAM_ERROR.getMsg());
        }

        CmCustomerSecondLevel secondLevel = null;

        if(StringUtils.isNotBlank(req.getIdNumber())) {
            //根据证件号和tenanId查询分路由
            CacheMapping cacheMappingChannel = cacheMappingService.selectCacheByIdNumberAndChannel(req.getTenantId(), req.getIdNumber(), req.getChannel(), true);
            logger.info("根据证件号[{}]租户[{}]获取路由信息[{}]", req.getIdNumber(), req.getTenantId(), cacheMappingChannel);
            if (null == cacheMappingChannel) {
                logger.info("客户不存在");
            } else {
                secondLevel = extCmCustomerSecondLevelMapper.selectByCustomerIdAndChannel(cacheMappingChannel.getCustomerId(), req.getChannel(), req.getTenantId());
            }
        }else {
            //根据手机号和tenanId查询分路由
            CacheMapping cacheMapping = cacheMappingService.selectFromByMobile(req.getTenantId(), req.getMobile(), true);
            logger.info("根据手机号[{}]租户[{}]获取路由信息[{}]", req.getMobile(), req.getTenantId(), cacheMapping);
            if (null == cacheMapping) {
                logger.info("客户不存在");
            } else {
                secondLevel = extCmCustomerSecondLevelMapper.selectByCustomerIdAndChannel(cacheMapping.getCustomerId(), cacheMapping.getChannel(), req.getTenantId());
            }
        }

        if(null == secondLevel){
            TlCustomerLabelLog tlCustomerLabelLog = new TlCustomerLabelLog();
            BeanMapping.copy(req,tlCustomerLabelLog);
            tlCustomerLabelLog.setOrganizationId(prPriceLabel.getOrganizationId());
            tlCustomerLabelLog.setLabelDesc(prPriceLabel.getLabelDesc());
            tlCustomerLabelLog.setUpdateBy("SYSTEM");
            try {
                tlCustomerLabelLog.setId(segmentService.getId(CustomerConstant.TL_CUSTOMER_LABEl_LOG_ID));
            } catch (SegmentException e) {
                logger.error("主键生成错误", e);
                throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
            }
            tlCustomerLabelLogService.saveTlCustomerLabelLog(tlCustomerLabelLog);

        }else {

            CmCustomerLabel cmCustomerLabel = new CmCustomerLabel();
            try {
                cmCustomerLabel.setId(segmentService.getId(CustomerConstant.CM_CUSTOMER_LABEl_ID));
            } catch (SegmentException e) {
                logger.error("主键生成错误", e);
                throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
            }
            cmCustomerLabel.setCustomerId(secondLevel.getCustomerId());
            cmCustomerLabel.setTenantId(req.getTenantId());
            cmCustomerLabel.setOrganizationId(secondLevel.getOrganizationId());
            cmCustomerLabel.setChannel(secondLevel.getChannel());
            cmCustomerLabel.setSeqNo(req.getSeqNo());
            cmCustomerLabel.setLabelStatus(CustomerConstant.YES_FLAG);
            cmCustomerLabel.setLabelCode(req.getLabelCode());
            cmCustomerLabel.setLabelDesc(prPriceLabel.getLabelDesc());
            cmCustomerLabel.setEffectiveDate(req.getEffectiveDate());
            cmCustomerLabel.setExpireDate(req.getExpireDate());
            cmCustomerLabel.setUpdateBy("SYSTEM");
            cmCustomerLabel.setRecordVersionNumber(1);

            cmCustomerLabelMapper.insertSelective(cmCustomerLabel);
        }

        CustomerLabelRes res = new CustomerLabelRes();
        res.setTenantId(req.getTenantId());
        res.setUserId(secondLevel==null?"":secondLevel.getUserId());
        return res;
    }

    @Override
    public CmCustomerLabel matchingCustomerLabel(String tenantId, String channel, String customerId, Date businessDate){
        //根据客户信息  当前业务日期  查询有效期范围内的客户标签  按更新时间倒序
        List<CmCustomerLabel> list = extCmCustomerLabelMapper.selectByCustomerIdAndStatusAndDate(tenantId,channel,customerId,CustomerConstant.RIGHTS_STATUS_1,businessDate);

        if(list!=null && list.size()>0){
            //取倒序第一条
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<CmCustomerLabel> buildCustomerLabel(List<TlCustomerLabelLog> labelLogList, String customerId) throws SegmentException {
        List<CmCustomerLabel> customerLabelList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(labelLogList)){
            for(TlCustomerLabelLog log:labelLogList){
                CmCustomerLabel cmCustomerLabel = new CmCustomerLabel();
                BeanMapping.copy(log, cmCustomerLabel);
                cmCustomerLabel.setId(segmentService.getId(CustomerConstant.CM_CUSTOMER_LABEl_ID));
                cmCustomerLabel.setCustomerId(customerId);
                cmCustomerLabel.setUpdateBy("SYSTEM");
                cmCustomerLabel.setRecordVersionNumber(1);
                cmCustomerLabel.setLabelStatus(CustomerConstant.YES_FLAG);
                cmCustomerLabel.setCreateTime(null);
                cmCustomerLabel.setUpdateTime(null);
                customerLabelList.add(cmCustomerLabel);
            }
        }
        return  customerLabelList;
    }

    @Override
    public void saveCustomerLabels(List<CmCustomerLabel> customerLabelList) {
        if (CollectionUtils.isNotEmpty(customerLabelList)) {
            customerLabelList = customerLabelList.stream().collect(Collectors.collectingAndThen(
                    Collectors.toCollection(() -> new TreeSet<CmCustomerLabel>(
                            Comparator.comparing(CmCustomerLabel::getLabelCode)
                                    .thenComparing(CmCustomerLabel::getLabelStatus)
                                    .thenComparing(CmCustomerLabel::getEffectiveDate)
                                    .thenComparing(CmCustomerLabel::getExpireDate))), ArrayList::new));
            customerLabelList.forEach(label -> extCmCustomerLabelMapper.insertSelective(label));
        }

    }
}
